package com.senta.elasticsearch.web.controller;



import com.senta.elasticsearch.entity.BillingItemDis;
import com.senta.elasticsearch.repository.BillingItemDisRepository;
import com.senta.elasticsearch.service.IBillingItemDisService;
import com.senta.elasticsearch.utils.EsUtil;
import com.senta.elasticsearch.utils.EsUtilBuilder;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.web.bind.annotation.*;

import java.util.Optional;

/**
 * @author anyang
 * Email: 1300378587@qq.com
 * Created Date:2019-11-19 11:07
 */
@RestController
@RequestMapping("billing")
@Slf4j
public class BillingItemDisController{
    @Autowired
    ElasticsearchTemplate elasticsearchTemplate;
    @Autowired
    IBillingItemDisService billingItemDisService;

    @Autowired
    BillingItemDisRepository billingItemDisRepository;

    @GetMapping("/byid/{id}")
    public Object getByPatientName(@PathVariable String id){
        Optional<BillingItemDis> byId = billingItemDisRepository.findById(id);
        if(byId != null){
            return byId.get();
        }
        return null;
    }

    /**
     * 期望为单线程访问，不允许多个同时触发该操作
     * @return
     */
    @PostMapping("/reinitEs")
    public String restoreElastic(){
        /*
        if(!elasticsearchTemplate.indexExists(BillingItemDis.class)) {
            log.info("索引不存在，正在创建索引");
            elasticsearchTemplate.createIndex(BillingItemDis.class);
            elasticsearchTemplate.putMapping(BillingItemDis.class);
            log.info("创建完毕");
        }else {
            elasticsearchTemplate.putMapping(BillingItemDis.class);
            billingItemDisRepository.deleteAll();
        }
        */

        final EsUtil esUtil = EsUtilBuilder.build(BillingItemDis.class);

        boolean result = esUtil.doDataToEsFromDB(150000L, elasticsearchTemplate, billingItemDisService);

        return result?"操作完成":"操作失败";
    }

    /**
     * {
     *   "query": {                --> builder
     *     "bool": {               --> boolQuery
     *       "must": [                 -->     boolQuery.must( ... )
     *         {"match": {"orderDoctor": "汪琳休"}},  -->MatchQueryBuilder
     *         {"match": {"patientName": "聂炎"}}
     *       ],
     *       "must_not": [                                -->boolQuery.mustNot( ... )
     *         {"match": {"itemClass1": "E"}}
     *       ],
     *       "should": [
     *         {"match": {"hosOutp": "住院"}},
     *         {"match": {"itemClass2": "治疗"}}
     *       ],
     *       "filter": {
     *         "term": {                                 --> QueryBuilders.termQuery("orderDoctorId", "12884")
     *           "orderDoctorId": "12884"
     *         }
     *       }
     *     }
     *   },
     *   "sort": [                                        ---> SortBuilders.fieldSort("pk").order(SortOrder.DESC)
     *     {
     *       "pk": {
     *         "order": "asc"
     *       }
     *     }
     *   ],
     *   "size": 308                                              --->  PageRequest.of(0,308)
     *   , "from": 0
     * }
     *
     * 实际代码的构建过程与查询语句的书写过程一致
     *
     * @return
     */
    @GetMapping("/query")
    public Page<BillingItemDis> queryFromEs(){


        NativeSearchQuery searchQuery = getSearchQuery();

        Page<BillingItemDis> search = billingItemDisRepository.search(searchQuery);

        return search;
    }

    /**
     * 获取需要传入的query对象的结构
     * 
     * @return
     */

    @GetMapping("/queryStructure")
    public  NativeSearchQuery getStructure(){

        return getSearchQuery();
    }




    private  NativeSearchQuery getSearchQuery(){
        /* 创建基础查询条件构建对象 */
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
        //创建bool查询对象
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

        //创建bool中的must-match
        MatchQueryBuilder matchOderDoctor = QueryBuilders.matchQuery("orderDoctor", "汪琳休");
        MatchQueryBuilder matchPatientName = QueryBuilders.matchQuery("patientName", "聂炎");

//        添加到boolQuery中
        boolQuery.must(matchOderDoctor);
        boolQuery.must(matchOderDoctor);

        //创建must not 需要的对象
        MatchQueryBuilder matchItemClass1 = QueryBuilders.matchQuery("itemClass1","E");
        //添加带boolQuery中
        boolQuery.mustNot(matchItemClass1);

        //创建should中的对象并添加
        MatchQueryBuilder matchHosOutp = QueryBuilders.matchQuery("hosOutp", "住院");
        MatchQueryBuilder matchItemClass2 = QueryBuilders.matchQuery("itemClass2", "治疗");
        boolQuery.should(matchHosOutp);
        boolQuery.should(matchItemClass2);

        /* //精确过滤 @TODO 添加过滤的时间范围条件 */

        TermQueryBuilder termOrderDoctorId = QueryBuilders.termQuery("orderDoctorId", "12884");
        boolQuery.filter(termOrderDoctorId);
        //在query中添加BbolQuery
        builder.withQuery(boolQuery);
        //在query后添加排序
        builder.withSort(SortBuilders.fieldSort("pk").order(SortOrder.DESC));
        //添加分页条件
        builder.withPageable(PageRequest.of(0,308));

        //添加完成所有条件后构建
        NativeSearchQuery searchQuery = builder.build();
        return searchQuery;
    }


}
